﻿#pragma once


#include <QMainWindow>
#include <QTimer>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QDir>
#include <QMessageBox>
#include <QWidget>
#include <QApplication>
#include <QHeaderView>
#include <QMenuBar>
#include <QPushButton>
#include <QTableWidget>
#include <QTextEdit>
#include <QStringList>
#include <QFileDialog>
#include <QSettings>
#include "QDesktopServices"
#include "QUrl"
#include "QListView"
#include "QStringListModel"
#include "QDesktopServices"
#include "QStringListModel"
#include <QProcess>
#include <QDockWidget>
#include <QDateTime>
#include <QTcpSocket>

using namespace std;
#include <iostream>
#include <string.h>

#include "modbus.h"

#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/fmt/ostr.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
extern std::shared_ptr<spdlog::logger> logger ;

#include "camera_qdialog.h"
#include "qt_hread_process.h"
#include "show_qlabel.h"
#include "commonfunction.h"

#include "login_dialog.h"


#include "recipe_dialog.h"

#include <QTextCodec>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();


    //产品切换
    LoadRecipeDialog  m_load_recipe_dialog;

    vector<vector<uint>> m_result_data_top;
    vector<vector<uint>> m_result_data_bottom;


    vector<vector<uint>> m_result_data;

	// 连续空料次数
	int m_empty_times=0;


    //图像显示
    vector<bool> m_vector_show_image;

    bool m_show_image;

    //存图线程
    SaveImageThread* m_save_image_thread = nullptr;
    QString m_save_image_dir;

    QString m_io_ip="";
    mutex mutex_io;

    int m_camera_number=0;///<成员变量m_camera_number,该视觉系统中，相机的总数量

    //主界面 图像显示
    QWidget* m_image_widget;
    vector< ShowQLabel*> m_vector_show_qlabel;
    //检测方法设置界面
    QDialog* m_qdialog_detection = nullptr;
    QTabWidget* m_tabwidget_detection = nullptr;
    vector<QtThreadProcess*>  m_vector_detection_thread;

    //相机设置界面
    QDialog* m_qdialog_camera = nullptr;
    QTabWidget* m_tabwidget_camera = nullptr;
    vector<CameraHKQDialog*> m_vector_camera;

    int m_online=0;///在线连接相机检测时，该值为1，离线检测时，该值为0

    QSettings* m_settings_para = nullptr;
    QString m_para_dir;
    QString m_exe_directory;
    QString m_type_dir = "type";
    QString m_type_name= "";
    QString m_save_data_dir="";

    // dockwidget pannel
    QDockWidget* m_qdockwidget_pannel= nullptr;
	vector< ShowQLabel*> m_vector_qlabel_ball;
    QPushButton *m_qpushbutton_para  = nullptr;

    QPushButton *m_qpushbutton_camera  = nullptr;
    QPushButton *m_qpushbutton_open_image_dir  = nullptr;
    QPushButton *m_qpushbutton_open_clear = nullptr;
    QPushButton *m_qpushbutton_user  = nullptr;
    QPushButton *m_qpushbutton_open_help  = nullptr;
    QPushButton *m_qpushbutton_exit  = nullptr;
    QPushButton *m_qpushbutton_open_type_dir= nullptr;


    // PLC pannel
    QDockWidget* m_qdockwidget_plc= nullptr;
    QPushButton *m_qpushbutton_start  = nullptr;
	QPushButton *m_qpushbutton_stop = nullptr;
	QLabel*      m_qlabel_remove_ball_positioan = nullptr;

    QLabel*      m_qlabel_ok_number = nullptr;
    QLabel*      m_qlabel_ok_ratio = nullptr;

	QLabel*      m_qlabel_all_number = nullptr;

	uint64_t m_error_number = 0;
    uint64_t m_all_number = 0;
    uint64_t m_empty_number = 0;
	//    //数据统计
	QString m_data_path = "";
	uint64_t m_error_number_last = 0;
	uint64_t m_all_number_last = 0;
	uint64_t m_empty_number_last = 0;

	QLabel*      m_qlabel_speed = nullptr;

    QDockWidget* m_qdockwidget_devicesizetable= nullptr;



    //modibus
    int m_unuse_use_modbus=0;
    modbus_t *m_modbus_tcp=nullptr;
    QString  m_modbus_ip;
    int      m_modbus_port;
    QTimer*  m_timer_plc  = nullptr;
    QStringList m_save_data_time;


	int address_ball_number = 2000    ;
	int value_ball_number = 8         ;

    int address_ball_row = 2001       ;
	int value_ball_row = 2            ;


    int address_gap_number=2002       ;
    int value_gap_number=9            ;

	int address_ball_times = 2003;
	int value_ball_times = 4;

    int address_ball_delay=2010       ;
	int value_ball_delay=100          ;

    int address_rotate_angle=2100     ;
    float value_rotate_angle=100        ;

    int address_rotate_speed=2102     ;
	float value_rotate_speed=100        ;

    int address_ok_position=2104      ;
	float value_ok_position=100         ;

    int address_ng_position=2106      ;
	float value_ng_position=100         ;

    int address_ok_ng_position=2108   ;
	float value_ok_ng_position=100      ;

    int address_ng_ok_position=2110   ;
	float value_ng_ok_position=100      ;

    int   address_remove_ball_speed=2102      ;
	float value_remove_ball_speed=100         ;

    int   address_remove_ball_positioan=2102  ;

	
    int address_adress_result = 501             ;

	
    //plc pannel
    int address_start_or_stop = 100           ;
    int value_start_or_stop    = 0           ;
    int address_calibration   = 102            ;
    int address_init          = 103           ;
    int address_ball_front    = 104            ;
    int address_ball_back     = 105             ;

    int address_ok_time_out =200                ;
    int address_ng_time_out =201                ;
    int address_ok_ng_time_out =202             ;
    int address_ng_ok_time_out =203           ;
    int address_detectiontime_out=204          ;
    int address_motor_error      =205           ;
    int address_motor_timeout      =206         ;
    int address_empty      =207          ;
    //登录对话框
    QString m_user_passward;
    QString m_admin_passeard;
    int m_login_privilege = 0;

    Login_Dialog* m_login_dialog;




public :
    void login();

	//void clickStart_or_stop();

    void clickPara();

    void clickCamera();

    void closeSoftware();

    void returnMainFrame();

    virtual void closeEvent(QCloseEvent* event) override;

    void saveImage(VectorOutputResult result);

    void showResult(VectorOutputResult result);

    void timerLoadImage();

    void timerPLC();

    bool loadPara();

    void initdockPannel();

    void initMainWindow();

    void initImageControl();
    void initPlcPannel();

    void clickStart();


    void clickStop();

    void createShowImage(int value_ball_number, int value_ball_row, vector<int > m_vector_result, Mat& image_out)
	{
		int width = 225;
		int height = 50;
		image_out = Mat(height, width, CV_8UC3, Scalar(255, 255, 255));



		for (int i = 0; i < value_ball_row; i++)
		{
			for (int j = 0; j < value_ball_number; j++)
			{
				Scalar scalar;
                if (m_vector_result[i*value_ball_number + j] == -1)
				{
					scalar = Scalar(0, 0, 255);
				}
                if (m_vector_result[i*value_ball_number + j] == -2)
                {
                    scalar = Scalar(0, 153, 255);
                }
				if (m_vector_result[i*value_ball_number + j] == 1)
				{
					scalar = Scalar(0, 255, 0);
				}
                if (m_vector_result[i*value_ball_number + j] == 0)
				{
					scalar = Scalar(0, 0, 0);
				}
				cv::circle(image_out, Point(j * 30 + 5, i * 20 + 15), 5, scalar, -1);
			}
		}
	}

    void float_to_registers(float f, uint16_t *regs) {
        union {
            float f;
            uint8_t bytes[4];
        } u;
        u.f = f;
        // 小端序，先存低字节
        regs[0] = (u.bytes[1] << 8) | u.bytes[0];
        regs[1] = (u.bytes[3] << 8) | u.bytes[2];
    }

    void timer_statistics();

    void loadRecipe();
};

#pragma execution_character_set("utf-8")
